package com.mo.xi.ge.info.help

import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.hardware.Sensor
import android.hardware.SensorManager
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import android.view.accessibility.AccessibilityManager
import java.io.File
import java.util.Locale

/**
 * date:2024/1/25
 * 模拟器检测
 **/
internal object DeviceCheckUUtil {
    /**
     * 检测是否是模拟器
     *
     * @param context  上下文
     * @param callback 回调
     * @return
     */
    fun deviceEmulator(
        context: Context?
    ): Boolean {
        return infoTryCatch(false) { readSysProperty(context) }
    }


    private fun readSysProperty(context: Context?): Boolean {
        if (strongCheckIsEmulator()) {
            return true
        }
        var suspectCount = 0
        val baseBandVersion = getProperty("gsm.version.baseband")
        if (baseBandVersion != null && baseBandVersion.contains("1.0.0.0")) ++suspectCount
        val buildFlavor = getProperty("ro.build.flavor")
        if (buildFlavor != null && (buildFlavor.contains("vbox") || buildFlavor.contains(
                "sdk_gphone"
            ))
        ) ++suspectCount
        val productBoard = getProperty("ro.product.board")
        if (productBoard != null && (productBoard.contains("android") || productBoard.contains(
                "goldfish"
            ))
        ) ++suspectCount
        val boardPlatform = getProperty("ro.board.platform")
        if (boardPlatform != null && boardPlatform.contains("android")) ++suspectCount
        val hardWare = getProperty("ro.hardware")
        if (null == hardWare) ++suspectCount else if (hardWare.lowercase(Locale.getDefault())
                .contains("ttvm")
        ) suspectCount += 10 else if (hardWare.lowercase(
                Locale.getDefault()
            ).contains("nox")
        ) suspectCount += 10
        var sensorNum = "sensorNum"
        if (context != null) {
            val sm = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
            val sensorSize = sm.getSensorList(Sensor.TYPE_ALL).size
            if (sensorSize < 7) ++suspectCount
            sensorNum += sensorSize
        }
//        callback?.let {
//            val stringBuffer = StringBuilder("ceshi start|")
//                .append(baseBandVersion).append("|")
//                .append(buildFlavor).append("|")
//                .append(productBoard).append("|")
//                .append(boardPlatform).append("|")
//                .append(hardWare).append("|")
//                .append(sensorNum).append("|")
//                .append("end")
//            callback.findEmulator(stringBuffer.toString())
//        }
        return suspectCount > 3
    }


    private fun getProperty(propName: String): String? {
        var value: String? = null
        val roSecureObj: Any?
        try {
            roSecureObj = Class.forName("android.os.SystemProperties")
                .getMethod("get", String::class.java)
                .invoke(null, propName)
            if (roSecureObj != null) value = roSecureObj as String?
        } catch (e: Exception) {
            value = null
        }
        return if (TextUtils.isEmpty(value)) null else value
    }

    private fun strongCheckIsEmulator(): Boolean {
        return (Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.startsWith("unknown")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion") || Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith(
            "generic"
        )) || "google_sdk" == Build.PRODUCT || "sdk" == Build.PRODUCT
    }

//    interface EmulatorCheckCallback {
//        fun findEmulator(emulatorInfo: String?)
//    }

    fun isDeviceRoot(): Boolean {
        val rootTag = arrayOf(
            "/su", "/su/bin/su", "/sbin/su",
            "/data/local/xbin/su", "/data/local/bin/su", "/data/local/su",
            "/system/xbin/su",
            "/system/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su",
            "/system/bin/cufsdosck", "/system/xbin/cufsdosck", "/system/bin/cufsmgr",
            "/system/xbin/cufsmgr", "/system/bin/cufaevdd", "/system/xbin/cufaevdd",
            "/system/bin/conbb", "/system/xbin/conbb"
        )
        return try {
            var hasRoot = false
            var rootDir: Array<String>
            val dirCount = rootTag.also { rootDir = it }.size
            for (i in 0 until dirCount) {
                val dir = rootDir[i]
                if (File(dir).exists()) {
                    hasRoot = true
                    break
                }
            }
            Build.TAGS != null && Build.TAGS.contains("test-keys") || hasRoot
        } catch (e: Exception) {
            false
        }
    }



    fun isAccessEnabled(context: Context): Boolean {
        try {// 检查AccessibilityService是否开启
            val am = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
            return am.isEnabled && isSpokenFeedbackServiceEnabled(context)
        } catch (e: Exception) {

        }
        return false
    }

    private fun isSpokenFeedbackServiceEnabled(context: Context): Boolean {
        val readerAction = "android.accessibilityservice.AccessibilityService"
        val readerCategory = "android.accessibilityservice.category.FEEDBACK_SPOKEN"

        val screenReaderIntent = Intent(readerAction).apply {
            addCategory(readerCategory)
        }

        val screenReaders = context.packageManager.queryIntentServices(screenReaderIntent, 0)

        return if (screenReaders.isEmpty()) false
        else when {
            Build.VERSION.SDK_INT >= 26 -> screenReaders.any {
                isAccessibilitySettingsOn(
                    context,
                    "${it.serviceInfo.packageName}/${it.serviceInfo.name}"
                )
            }
            else -> {
                val runningServices = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
                val runningServiceNames = runningServices.getRunningServices(Int.MAX_VALUE)
                    .map { it.service.packageName }
                screenReaders.any { runningServiceNames.contains(it.serviceInfo.packageName) }
            }
        }
    }


    private fun isAccessibilitySettingsOn(context: Context, service: String): Boolean =
        Settings.Secure.getString(
            context.applicationContext.contentResolver,
            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
        )?.split(":")?.any { it.equals(service, ignoreCase = true) } ?: false
}
